package com.http.bio;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author YL
 */
public class HttpServer {

    private static ThreadPoolExecutor THREAD_POOL;

    static {
        THREAD_POOL = new ThreadPoolExecutor(
                10,
                200,
                30,
                TimeUnit.MINUTES,
                new LinkedBlockingQueue<>(1000),
                (r) -> new Thread(r, "HttpServer")
        );
    }

    public static void main(String[] args) {
        ServerSocket serverSocket;

        try {
            // 建立服务器Socket,监听客户端请求
            serverSocket = new ServerSocket(80);
            System.out.println("Server is running on port:" + serverSocket.getLocalPort());
            // 循环监听客户端请求
            while (true) {
                final Socket socket = serverSocket.accept();
                System.out.println("the client address:" +
                        socket.getInetAddress() + ":" + socket.getPort());
                socket.setKeepAlive(true);
                socket.setTcpNoDelay(true);
                // 并发处理HTTP客户端请求
                HttpServer.service(socket);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void service(Socket socket) {
        THREAD_POOL.execute(() -> {
            InputStream inSocket;
            try {
                // 获取HTTP请求头
                inSocket = socket.getInputStream();
                int size = inSocket.available();
                byte[] buffer = new byte[size];
                inSocket.read(buffer);
                String request = new String(buffer);
                System.out.println("ClientBrowser:\n" + request + "\n"
                        + "------------------------------------------------------------------");

                String firstLineOfRequest;
                String[] heads;
                String uri = "";
                // 声明响应类型和编码格式
                String contentType = "text/html;charset=utf-8";
                if (request.length() > 0) {
                    firstLineOfRequest = request.substring(0, request.indexOf("\r\n"));
                    heads = firstLineOfRequest.split(" ");
                    uri = heads[1];
                }

                //将响应头发送给客户端
                String responseFirstLine = "HTTP/1.1 200 OK\r\n";

                String responseHead = "Content-Type:" + contentType + "\r\n";
                String keepAlive = "Connection: keep-alive\r\n";

                System.out.println("ServerResponse:\n" + responseFirstLine + "\n" + responseHead + "\n"
                        + "--------------------------------------------------------------------");

                OutputStream outSocket = socket.getOutputStream();
                outSocket.write(responseFirstLine.getBytes());
                outSocket.write(responseHead.getBytes());
                // outSocket.write(keepAlive.getBytes());

                // 分隔符
                outSocket.write("\r\n".getBytes());

                // 通过HTTP请求中的uri读取相应文件发送给客户端
                outSocket.write(("<H1>成功 URI: " + uri + "</H1>").getBytes());
                // inSocket.close();
                outSocket.flush();

                outSocket.write(("<H1>成功 URI: " + uri + "</H1>").getBytes());
                outSocket.flush();

                if (uri.equals("c")) {
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }

}
